﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;
using System.Data.SqlClient; // Bliver benyttet når vi skal arbejde med sql database

using Model;
using Interface;

namespace Controller
{
    // Den klasse er lavet af Gruppe 4 DM12a
    class DBFacade
    {
        SqlCommand sqlCommand; // de to vigtigste klasser når vi arbejder med database. command fortæller hvad den skal gøre
        SqlConnection sqlConnection; // connection fortæller om der er forbindelse til databasen

        string connectionString; // lav en lokal connection string til databasen, så der er forbindelse

        BookingController bookingController; // vi referer til bookingcontrolleren
        SqlDataReader datareader; // læser data i databasetabellerne

        public DBFacade(BookingController minBookingController)
        {
            bookingController = minBookingController; // Nu kender DBFacaden bookingcontrolleren

            connectionString = "Data Source=ealdb1.eal.local;User ID=ejl02_usr;Password=Baz1nga2;Initial Catalog=EJL02_DB;Trusted_connection=False";

            sqlConnection = new SqlConnection(connectionString); // Nu ved den hvilken database der arbejdes med

            sqlCommand = new SqlCommand();
            sqlCommand.Connection = sqlConnection; // tilknyt connection til command
            sqlCommand.CommandType = CommandType.StoredProcedure; // vi benytter stored procedures i sql database
        }

        #region Indlæs forbrug, værelser, post og tilbehør.

        // Denne metode er lavet af Ismail
        public void IndlæsForbrug()
        {
            datareader = null; //Skal referere til indlæst data
            int forbrugId = 0;
            decimal pris;
            int bookingId = 0;
            int værelseId = 0;
            sqlCommand.Parameters.Clear(); // vi nulstiller parameterne inden der udføres noget
            sqlCommand.CommandText = "IndlæsForbrug"; // fortæller hvilken stored procedure der arbejdes med

            try
            {
                sqlConnection.Open(); // åben connection
                datareader = sqlCommand.ExecuteReader();// læs og tag data med tilbage
                while (datareader.Read()) // while løkke der læser hvad der er i tabellen indtil der ikke er mere
                {
                    forbrugId = int.Parse(datareader["forbrugsId"].ToString()); // den lokale variabel sættes = kolonnen i databasen
                    pris = decimal.Parse(datareader["pris"].ToString());
                    bookingId = int.Parse(datareader["bookingId"].ToString());
                    værelseId = int.Parse(datareader["værelseId"].ToString());

                    // if-sætning der fortæller om den skal oprette et forbrug hvis forbruget ikke eksistere
                    if (forbrugId == 0)
                    {
                        bookingController.OpretForbrug(pris, forbrugId);
                    }
                    // else skal den vise tilkytning mellem værelse og forbrug
                    else
                    {
                        bookingController.OpretForbrug(pris, forbrugId);
                        bookingController.TilknytForbrugTilVærelse(forbrugId, værelseId, bookingId);
                    }
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        // metoden er lavet af Søren
        public void IndlæsBookedeVærelser()
        {
            datareader = null; // skal referere til indlæst data
            int værelseId = 0, størrelse = 0, bookingId = 0;
            string type;
            decimal pris = 0;
            bool morgenmad;
            string billed;
            sqlCommand.Parameters.Clear();
            sqlCommand.CommandText = "HentVærelserMedBooking";

            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    værelseId = int.Parse(datareader["værelseId"].ToString());
                    type = datareader["type"].ToString();
                    størrelse = int.Parse(datareader["størrelse"].ToString());
                    pris = decimal.Parse(datareader["pris"].ToString());
                    morgenmad = bool.Parse(datareader["morgenmad"].ToString());
                    billed = datareader["billede"].ToString();
                    bookingId = int.Parse(datareader["bookingId"].ToString());

                    if (værelseId == 0)
                    {
                        bookingController.OpretVærelse(værelseId, type, pris, størrelse, morgenmad, billed);
                    }
                    else
                    {
                        bookingController.TilknytBookingTilVærelse(bookingId, værelseId);
                    }
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        // Metoden er lavet af Nirujan
        public void IndlæsVærelser()
        {
            datareader = null; // skal referere til indlæst data
            int værelseId = 0, størrelse = 0;
            string type;
            decimal pris = 0;
            bool morgenmad;
            string billed;
            sqlCommand.Parameters.Clear(); // Tøm parameterlisten, Hent_værelser har ingen parametre
            sqlCommand.CommandText = "Hent_værelser";

            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    værelseId = int.Parse(datareader["værelseId"].ToString());
                    type = datareader["type"].ToString();
                    størrelse = int.Parse(datareader["størrelse"].ToString());
                    pris = decimal.Parse(datareader["pris"].ToString());
                    morgenmad = bool.Parse(datareader["morgenmad"].ToString());
                    billed = datareader["billede"].ToString();

                    bookingController.OpretVærelse(værelseId, type, pris, størrelse, morgenmad, billed);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        // metoden er lavet af Nirujan
        public void IndlæsTilbehør()
        {
            datareader = null; // skal referere til indlæst data
            int tilbehørId;
            string betegnelse;
            decimal pris;
            sqlCommand.Parameters.Clear();
            sqlCommand.CommandText = "sp_tilbehør";

            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    tilbehørId = int.Parse(datareader["tilbehørId"].ToString());
                    betegnelse = datareader["betegnelse"].ToString();
                    pris = int.Parse(datareader["pris"].ToString());

                    bookingController.GemTilbehør(tilbehørId, betegnelse, pris);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        // metoden er lavet af Visi
        public void IndlæsKøbtTilbehør()
        {
            datareader = null; // skal referere til indlæst data
            
            int tilbehørId;
            string betegnelse;
            decimal pris;
            int forbrugId;
            sqlCommand.Parameters.Clear();
            sqlCommand.CommandText = "HentTilbehørTilknyttetTilForbrug";

            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    tilbehørId = int.Parse(datareader["tilbehørId"].ToString());
                    betegnelse = datareader["betegnelse"].ToString();
                    pris = int.Parse(datareader["pris"].ToString());
                    forbrugId = int.Parse(datareader["forbrugsId"].ToString());

                    if (tilbehørId == 0)
                    {
                        bookingController.GemTilbehør(tilbehørId, betegnelse, pris);
                    }
                    else
                    {
                        bookingController.TilknytTilbehørTilForbrug(tilbehørId, forbrugId);
                    }
                    
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        #endregion 

        #region Indlæs/Opret/Slet/Rediger kunde

        // metoden er lavet Søren
        public void IndlæsKunder()
        {
            datareader = null; // skal referere til indlæst data
            int kundeId = 0, tlfNr = 0;
            string navn, adresse, email, postNr, distrikt, land;
            sqlCommand.Parameters.Clear();
            sqlCommand.CommandText = "Hent_Kunde";

            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader(); // læs og tag data med tilbage

                while (datareader.Read())  // så længe der er rækker i datareaderen
                {
                    kundeId = int.Parse(datareader["kundeId"].ToString());
                    navn = datareader["navn"].ToString(); // find denne rækkes navn
                    adresse = datareader["adresse"].ToString();
                    postNr = datareader["PostNr"].ToString();
                    distrikt = datareader["distrikt"].ToString();
                    tlfNr = int.Parse(datareader["tlf"].ToString());
                    email = datareader["email"].ToString();
                    land = datareader["land"].ToString();

                    bookingController.OpretKunde(navn, adresse, postNr, distrikt, tlfNr, email, kundeId, land);
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        // metoden er lavet af Ismail
        public int OpretKunde(string navn, string adresse, string postNr, int tlf, string email, string land)
        {
            sqlCommand.CommandText = "OpretNyKunde"; // fortæl hvilken stored procedure
            sqlCommand.Parameters.Clear(); // tøm parameterlisten

            int kundeId = 0;
            // sæt værdier ind i parametrene
            SqlParameter par = new SqlParameter("@kundeId", SqlDbType.Int); // der instantieres en ny parameter til tabellen
            par.Value = kundeId; // den nye parameter sættes = den lokale parameter
            par.Direction = ParameterDirection.Output; // Outputtet fortæller hvilken primary key det er
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@navn", SqlDbType.VarChar);
            par.Value = navn;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@adresse", SqlDbType.VarChar);
            par.Value = adresse;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@postNr", SqlDbType.VarChar);
            par.Value = postNr;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@tlf", SqlDbType.Int);
            par.Value = tlf;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@email", SqlDbType.VarChar);
            par.Value = email;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@land", SqlDbType.VarChar);
            par.Value = land;
            sqlCommand.Parameters.Add(par);

            try
            {
                sqlConnection.Open(); // Åben forbindelsen til databasen
                sqlCommand.ExecuteNonQuery(); // den executer sql erklæringen til databasen og returnere de felter som er påvirket
                kundeId = (int.Parse(sqlCommand.Parameters["@kundeId"].Value.ToString())); // returner datatypen som er kundeId
                return kundeId;
            }

            catch (SqlException e)
            {
                throw e;
            }

            finally  // eksekveres altid
            {
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close(); // hvis connection var åben: så luk!!
                }
            }
        }

        // metoden er lavet af Nirujan og Ismail
        public int SletKunde(int kundeId)
        {
            sqlCommand.CommandText = "sp_SletKunde"; // fortæl hvilken stored procedure
            sqlCommand.Parameters.Clear(); // tøm parameterlisten

            // sæt værdier ind i parametrene
            SqlParameter par = new SqlParameter("@kundeId", SqlDbType.Int);
            par.Value = kundeId;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            try
            {
                sqlConnection.Open(); // Åben forbindelsen til databasen
                sqlCommand.ExecuteNonQuery(); // FEJL!
                return (int.Parse(sqlCommand.Parameters["@kundeId"].Value.ToString()));
            }

            catch (SqlException e)
            {
                throw e;
            }

            finally  // eksekveres altid
            {
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close(); // hvis connection var åben: så luk!!
                }
            }
        }

        // metoden er lavet af Søren
        public int RedigerKunde(int kundeId, string navn, string adresse, int tlf, string email, string land)
        {
            datareader = null;
            sqlCommand.CommandText = "RetKunde";
            sqlCommand.Parameters.Clear();

            SqlParameter par = new SqlParameter("@kundeId", SqlDbType.Int);
            par.Value = kundeId;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@navn", SqlDbType.VarChar);
            par.Value = navn;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@adresse", SqlDbType.VarChar);
            par.Value = adresse;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@email", SqlDbType.VarChar);
            par.Value = email;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@tlfNr", SqlDbType.Int);
            par.Value = tlf;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@land", SqlDbType.VarChar);
            par.Value = land;
            sqlCommand.Parameters.Add(par);

            try
            {
                sqlConnection.Open(); // Åben forbindelsen til databasen
                sqlCommand.ExecuteNonQuery(); 
                return (int.Parse(sqlCommand.Parameters["@kundeId"].Value.ToString()));
            }

            catch (SqlException e)
            {
                throw e;
            }

            finally  // eksekveres altid
            {
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close(); // hvis connection var åben: så luk!!
                }
            }
        }

        #endregion

        #region Opret/Indlæs Booking

        // metoden er lavet af Ismail
        public int OpretBooking(DateTime ankomst, DateTime afrejse, int antalVærelser, int antalPersoner, int kundeId, int værelseId, decimal pris)
        {
            int bookingId = 0;

            sqlCommand.CommandText = "OpretNyBooking"; // fortæl hvilken stored procedure
            sqlCommand.Parameters.Clear(); // tøm parameterlisten

            // sæt værdier ind i parametrene
            SqlParameter par = new SqlParameter("@bookingId", SqlDbType.Int);
            par.Value = bookingId;
            par.Direction = ParameterDirection.Output;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@ankomst", SqlDbType.DateTime);
            par.Value = ankomst;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@afrejse", SqlDbType.DateTime);
            par.Value = afrejse;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@antalVærelser", SqlDbType.Int);
            par.Value = antalVærelser;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@antalPersoner", SqlDbType.Int);
            par.Value = antalPersoner;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@kundeId", SqlDbType.Int);
            par.Value = kundeId;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@værelseId", SqlDbType.Int);
            par.Value = værelseId;
            sqlCommand.Parameters.Add(par);

            try
            {
                sqlConnection.Open(); // Åben forbindelsen til databasen
                sqlCommand.ExecuteNonQuery();
                return (int.Parse(sqlCommand.Parameters["@bookingId"].Value.ToString()));
            }

            catch (SqlException e)
            {
                throw e;
            }

            finally  // eksekveres altid
            {
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close(); // hvis connection var åben: så luk!!
                }
            }
        }

        // metoden er lavet af Søren
        public void IndlæsBooking()
        {
            datareader = null; //Skal referere til indlæst data
            DateTime ankomst;
            DateTime afrejse;
            int antalVærelser = 0;
            int antalPersoner = 0;
            int bookingId = 0;
            int kundeId = 0;
            sqlCommand.Parameters.Clear();
            sqlCommand.CommandText = "IndlæsBooking";

            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader();// læs og tag data med tilbage
                while (datareader.Read())
                {
                    ankomst = DateTime.Parse(datareader["ankomst"].ToString());
                    afrejse = DateTime.Parse(datareader["afrejse"].ToString());
                    antalVærelser = int.Parse(datareader["antalVærelser"].ToString());
                    antalPersoner = int.Parse(datareader["antalPersoner"].ToString());
                    bookingId = int.Parse(datareader["bookingId"].ToString());
                    kundeId = int.Parse(datareader["kundeId"].ToString());

                    if (bookingId == 0)
                    {
                        bookingController.OpretBooking(ankomst, afrejse, antalVærelser, antalPersoner, bookingId);
                    }
                    else
                    {
                        bookingController.OpretBooking(ankomst, afrejse, antalVærelser, antalPersoner, bookingId);
                        bookingController.TilknytKundeTilBooking(kundeId);
                    }
                }
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            finally
            {
                // close the reader
                if (datareader != null)
                {
                    datareader.Close();
                }
                // close the connection
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close();
                }
            }
        }

        #endregion

        // metoden er lavet af Søren
        public string HentByer(string postNummer)
        {
            datareader = null;
            string by = string.Empty;
            sqlCommand.CommandText = "Hent_Byer";
            sqlCommand.Parameters.Clear();

            SqlParameter par = new SqlParameter("@postNr", SqlDbType.VarChar);
            par.Value = postNummer;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten
            
            try
            {
                sqlConnection.Open();
                datareader = sqlCommand.ExecuteReader();
                while (datareader.Read() == true)
                {
                    by = datareader["Distrikt"].ToString();
                }
            }
            catch
            { }
            finally
            {
                if (sqlConnection != null)
                    sqlConnection.Close();
            }

            return by;
        }

        // metoden er lavet af Visi
        public int GemTilbehør(int tilbehørId, int forbrugsId, decimal pris)
        {
            sqlCommand.CommandText = "TilføjTilbehør"; // fortæl hvilken stored procedure
            sqlCommand.Parameters.Clear(); // tøm parameterlisten

            // sæt værdier ind i parametrene
            SqlParameter par = new SqlParameter("@tilbehørId", SqlDbType.Int);
            par.Value = tilbehørId;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@forbrugId", SqlDbType.Int);
            par.Value = forbrugsId;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@pris", SqlDbType.Decimal);
            par.Value = pris;
            sqlCommand.Parameters.Add(par);

            try
            {
                sqlConnection.Open(); // Åben forbindelsen til databasen
                sqlCommand.ExecuteNonQuery();
                return (int.Parse(sqlCommand.Parameters["@tilbehørId"].Value.ToString()));
            }

            catch (SqlException e)
            {
                throw e;
            }

            finally  // eksekveres altid
            {
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close(); // hvis connection var åben: så luk!!
                }
            }
        }

        // metoden er lavet af Visi
        public int OpretForbrug(decimal pris, int bookingId)
        {
            int forbrugId = 0;

            sqlCommand.CommandText = "OpretForbrug"; // fortæl hvilken stored procedure
            sqlCommand.Parameters.Clear(); // tøm parameterlisten

            // sæt værdier ind i parametrene
            SqlParameter par = new SqlParameter("@forbrugsId", SqlDbType.Int);
            par.Value = forbrugId;
            par.Direction = ParameterDirection.Output;
            sqlCommand.Parameters.Add(par); // gem parameteren i parameterlisten

            par = new SqlParameter("@bookingId", SqlDbType.Int);
            par.Value = bookingId;
            sqlCommand.Parameters.Add(par);

            par = new SqlParameter("@pris", SqlDbType.Decimal);
            par.Value = pris;
            sqlCommand.Parameters.Add(par);

            try
            {
                sqlConnection.Open(); // Åben forbindelsen til databasen
                sqlCommand.ExecuteNonQuery();
                return (int.Parse(sqlCommand.Parameters["@forbrugsId"].Value.ToString()));
            }

            catch (SqlException e)
            {
                throw e;
            }

            finally  // eksekveres altid
            {
                if (sqlConnection.State == ConnectionState.Open)
                {
                    sqlConnection.Close(); // hvis connection var åben: så luk!!
                }
            }
        }
    }
}
